<template>
  <el-select
    v-model="selValue"
    filterable
    placeholder="请选择"
    style="width: 100%;"
    @visible-change="visibleChange">
    <el-option
      v-for="item in _d.options"
      :key="item[valueKey]"
      :label="item[labelKey]"
      :value="item[valueKey]">
      <div>{{formatLabelFn(item)}}</div>
    </el-option>
  </el-select>
</template>

<script setup>
	import { reactive, ref, computed, watch, onMounted } from 'vue'
	import {$get, $post} from '/@/utils/request';
	import {getId} from "/@/utils/Tools.js";
	
	const emits = defineEmits(['update:modelValue'])

	const props = defineProps({
		modelValue: {
			type: [Number, String, null],
			default: ''
		},
		options: {
			type: Array,
			default: () => ([])
		},
		url: {
			type: String,
			default: ''
		},
		method: {
			type: String,
			default: 'get'
		},
		labelKey: {
			type: String,
			value: 'name'
		},
		valueKey: {
			type: String,
			value: 'id'
		},
		formatLabel: {
			type: String,
			default: ''
		},
	})

	const _d = reactive({
		options: []
	})

	const labelKey = computed(() => {
		return props.labelKey || 'name';
	})

	const valueKey = computed(() => {
		return props.valueKey || 'id';
	})

	const selValue = computed({
		get: () => {
			if(props.modelValue) {
				return JSON.parse(props.modelValue).id;
			}
			return '';
		},
		set: val => {
			let obj = _d.options.find(item => item[valueKey.value] == val);
			emits('update:modelValue', JSON.stringify({
				id: obj[valueKey.value],
				name: obj[labelKey.value]
			}));
		}
	})

	watch(() => props.options, (val) => {
		_d.options = val;
	}, {
		immediate: true
	})
	
	onMounted(() => {
		getOptions();
	})

	// 获取列表
	function getOptions() {
		if(!props.url) {
			return;
		}
		if(props.method == 'get') {
			$get(props.url).then(res => {
				_d.options = res.result;
			})
		} else if(props.method == 'post') {
			$post(props.url).then(res => {
				_d.options = res.result;
			})
		}
			
	}

	function visibleChange(show) {
		if(show) {
			getOptions();
		}
	}

	// 格式化显示内容
	let fnName = 'formatLabel'+getId(5);
	function formatLabelFn(row) {
		if(props.formatLabel) {
			let code = `window.${fnName} = function (row) {${props.formatLabel}}`;
			eval(code);
			return window[fnName](row);
		} else {
			return row[labelKey.value];
		}
	}

</script>

<style scoped>

</style>